
import { PiniaPluginContext } from 'pinia'

export interface AdvancedPersistOptions {
	key ?: string
	storage ?: 'local' | 'session'
	paths ?: string[]
	expire ?: number // 过期时间（小时）
	encrypt ?: boolean // 是否加密
}

export function createAdvancedPersistedState(options ?: AdvancedPersistOptions) {
	return (context : PiniaPluginContext) => {
		const { store } = context
		const {
			key = store.$id,
			storage = 'local',
			paths,
			expire,
			encrypt = false
		} = options || {}

		const storageKey = `pinia-${key}`

		// 尝试获取存储的数据
		const storedData = uni.getStorageSync(storageKey)

		if (storedData) {
			try {
				let data = JSON.parse(storedData)

				// 检查是否加密
				if (encrypt) {
					data = decryptData(data)
				}

				// 检查过期时间
				if (expire && data._timestamp) {
					const now = Date.now()
					const storedTime = data._timestamp
					if (now - storedTime > expire * 60 * 60 * 1000) {
						// 数据已过期，清除
						uni.removeStorageSync(storageKey)
						return
					}
				}

				// 恢复数据（移除时间戳）
				if (data._timestamp) {
					delete data._timestamp
				}

				// 应用数据到store
				if (paths && paths.length > 0) {
					const partialState : any = {}
					paths.forEach(path => {
						const value = getValueByPath(data, path)
						if (value !== undefined) {
							setValueByPath(partialState, path, value)
						}
					})
					store.$patch(partialState)
				} else {
					store.$patch(data)
				}
			} catch (error) {
				console.error(`Failed to parse persisted state for ${store.$id}:`, error)
			}
		}

		// 订阅store变化
		store.$subscribe((mutation, state) => {
			let dataToSave : any = state

			// 如果指定了路径，只保存部分状态
			if (paths && paths.length > 0) {
				dataToSave = {}
				paths.forEach(path => {
					const value = getValueByPath(state, path)
					if (value !== undefined) {
						setValueByPath(dataToSave, path, value)
					}
				})
			}

			// 添加时间戳用于过期检查
			if (expire) {
				dataToSave._timestamp = Date.now()
			}

			// 加密数据
			if (encrypt) {
				dataToSave = encryptData(dataToSave)
			}

			try {
				uni.setStorageSync(storageKey, JSON.stringify(dataToSave))
			} catch (error) {
				console.error(`Failed to persist state for ${store.$id}:`, error)

				// 处理存储空间不足的情况
				if (error.name === 'QuotaExceededError') {
					console.warn('Storage quota exceeded, clearing old data')
					// 可以在这里实现LRU等缓存清理策略
				}
			}
		})
	}
}

// 简单的加密解密函数（实际项目中应使用更安全的加密方式）
function encryptData(data : any) : string {
	return btoa(JSON.stringify(data)) // 简单base64编码
}

function decryptData(encrypted : string) : any {
	try {
		return JSON.parse(atob(encrypted))
	} catch {
		return null
	}
}

// 辅助函数：根据路径获取对象中的值
function getValueByPath(obj : any, path : string) {
	return path.split('.').reduce((acc, part) => acc && acc[part], obj)
}

// 辅助函数：根据路径设置对象中的值
function setValueByPath(obj : any, path : string, value : any) {
	const parts = path.split('.')
	const last = parts.pop()
	let current = obj

	for (const part of parts) {
		if (!current[part]) {
			current[part] = {}
		}
		current = current[part]
	}

	if (last) {
		current[last] = value
	}
}